-- ProfilesHard.lua — export/import explicites (General + Colors + Healer)
local ADDON, DFFT = ...
if not DFFT or type(DFFT.DB) ~= "table" then return end
local DB = DFFT.DB

local function deepcopy(x)
  if type(x) ~= "table" then return x end
  local t = {}
  for k,v in pairs(x) do t[k] = deepcopy(v) end
  return t
end
local function trim(s) return (tostring(s or ""):gsub("^%s+",""):gsub("%s+$","")) end
local function charKey()
  local name  = UnitName and UnitName("player") or "Unknown"
  local realm = GetNormalizedRealmName and GetNormalizedRealmName() or GetRealmName and GetRealmName() or "Realm"
  return tostring(name) .. "-" .. tostring(realm)
end
local function nowISO() if date then return date("!%Y-%m-%d %H:%M:%S") end return "unknown" end
local function p(...) print("|cffffd100DFFT:|r", ...) end

-- Clés explicitement gérées (onglets General + Colors)
local TOP_KEYS = {
  "globalAnchorToTarget",
  "playerSideSpread",
  "textSizePreset",
  "showSmall", "showMedium",
  "enableShake","shakeEnabled",
  "enableZoom",
  "UltraFXEnabled",
  "showCritSymbol",
  "fontName",
  "hideDefaultCombatText",
  "bigCritShadowEnabled",

  -- Colors (damage)
  "damageTheme",
  "smallColor","mediumColor","bigColor","veryBigColor","nonTargetColor",
  "smallAlpha","mediumAlpha","bigAlpha","veryBigAlpha","nonTargetAlpha",
  -- alias éventuels vus dans l’addon
  "bigTextAlpha","critAlpha","ultraAlpha",
}

-- Export “dur” : on prend les TOP_KEYS + tout le bloc healer (+ minimap.hide si présent)
local function exportConfig()
  local out = { _meta = { savedAt = nowISO(), version = DFFT.version or "" } }

  for _,k in ipairs(TOP_KEYS) do
    if DB[k] ~= nil then out[k] = deepcopy(DB[k]) end
  end

  -- healer (entier)
  if DB.healer then out.healer = deepcopy(DB.healer) end

  -- minimap.hide si présent (utile pour l’icône)
  if type(DB.minimap)=="table" and DB.minimap.hide ~= nil then
    out.minimap = { hide = not not DB.minimap.hide }
  end

  -- quelques caps nontarget courants qu’on voit parfois
  local caps = { "nonTargetSmallAlphaCap","nonTargetMediumAlphaCap","nonTargetBigAlphaCap","nonTargetVeryBigAlphaCap" }
  for _,k in ipairs(caps) do if DB[k] ~= nil then out[k] = DB[k] end end

  return out
end

local function applyIfNumber(k, v)
  if type(v)=="number" then DB[k]=v end
end
local function applyIfBool(k, v) DB[k] = not not v end
local function applyIfTable(k, v) if type(v)=="table" then DB[k]=deepcopy(v) end end
local function applyLoose(k, v) DB[k] = deepcopy(v) end

-- Import : on ré-écrit uniquement ce qu’on gère, puis on notifie l’engine
local function importConfig(cfg)
  if type(cfg) ~= "table" then return end

  -- 1) Appliquer tous les champs déclarés (y compris couleurs/alphas)
  for _,k in ipairs(TOP_KEYS) do
    local v = cfg[k]
    if v ~= nil then
      if type(v)=="number" then applyIfNumber(k, v)
      elseif type(v)=="boolean" then applyIfBool(k, v)
      elseif type(v)=="table" then applyIfTable(k, v)
      else applyLoose(k, v) end
    end
  end

  -- 2) Healer complet (inclut couleurs pickers healer)
  if cfg.healer then DB.healer = deepcopy(cfg.healer) end

  -- 3) minimap.hide
  if cfg.minimap and type(cfg.minimap.hide) ~= "nil" then
    DB.minimap = DB.minimap or {}
    DB.minimap.hide = not not cfg.minimap.hide
    if DFFT.SetMinimapHidden then pcall(DFFT.SetMinimapHidden, DB.minimap.hide) end
  end

  -- 4) caps éventuels
  for _,k in ipairs({ "nonTargetSmallAlphaCap","nonTargetMediumAlphaCap","nonTargetBigAlphaCap","nonTargetVeryBigAlphaCap" }) do
    if cfg[k] ~= nil then DB[k] = cfg[k] end
  end

  -- 5) (IMPORTANT) Thèmes :
  --    Si des couleurs de pickers sont présentes dans le profil, on NE ré-applique PAS le thème,
  --    pour ne pas écraser les pickers. On n’applique le thème que si le profil n’a pas de couleurs.
  local hasDamagePickerColors =
      (cfg.smallColor and cfg.mediumColor and cfg.bigColor and cfg.veryBigColor and cfg.nonTargetColor) ~= nil

  if not hasDamagePickerColors and type(DFFT.ApplyDamageTheme)=="function" and cfg.damageTheme then
    pcall(DFFT.ApplyDamageTheme, cfg.damageTheme)
  end
  -- (healer) : on a déjà DB.healer.colors.*; on n’applique pas de healTheme pour préserver les pickers.

  -- 6) Synchronisations/refresh engine (polices, palettes, absorptions, FCT Blizzard, etc.)
  if type(DFFT.refreshActiveFonts)=="function" then pcall(DFFT.refreshActiveFonts) end
  if type(DFFT.RefreshPalette)=="function"     then pcall(DFFT.RefreshPalette)     end
  if type(DFFT.RebuildColors)=="function"      then pcall(DFFT.RebuildColors)      end
  if DFFT.Healer then
    if type(DFFT.Healer.RefreshPalette)=="function" then pcall(DFFT.Healer.RefreshPalette) end
    if type(DFFT.Healer.RebuildColors)=="function"  then pcall(DFFT.Healer.RebuildColors)  end
    if type(DFFT.Healer.SetAbsorbsEnabled)=="function" and DB.healer and DB.healer.absorbs then
      pcall(DFFT.Healer.SetAbsorbsEnabled, not not (DB.healer.absorbs.show or DB.healer.absorbsEnabled or DB.showAbsorbs))
    end
  end
  if type(DFFT.SetBigCritShadowEnabled)=="function" and cfg.bigCritShadowEnabled ~= nil then
    pcall(DFFT.SetBigCritShadowEnabled, not not cfg.bigCritShadowEnabled)
  end
  if type(DFFT.ApplyDefaultCombatTextSetting)=="function" then pcall(DFFT.ApplyDefaultCombatTextSetting) end
  if type(DFFT.OnConfigChanged)=="function" then pcall(DFFT.OnConfigChanged, "profileHard") end
end

-- Remplace Save/Load par la version “hard-wired”
DFFT.Profile = DFFT.Profile or {}

local function ensureStores()
  DB._profiles = DB._profiles or {}
  DB._charToProfile = DB._charToProfile or {}
end

function DFFT.Profile.Save(name)
  name = trim(name)
  if name == "" then return false, "empty name" end
  ensureStores()
  local snap = exportConfig()
  DB._profiles[name] = snap
  DB._lastAppliedProfile = name

  -- petit résumé
  local keys = {}
  for k,_ in pairs(snap) do if k ~= "_meta" then table.insert(keys, k) end end
  table.sort(keys)
  p(("Profile saved: %s (fields=%d)"):format(name, #keys))
  return true
end

function DFFT.Profile.Load(name, makeActiveForThisChar)
  name = trim(name)
  ensureStores()
  local snap = DB._profiles[name]
  if not snap then return false, "profile not found" end

  importConfig(snap)

  DB._lastAppliedProfile = name
  if makeActiveForThisChar then
    DB._charToProfile[charKey()] = name
  end

  local fields = 0
  for k,_ in pairs(snap) do if k~="_meta" then fields = fields + 1 end end
  p(("<<< Profile loaded: %s (fields=%d)"):format(name, fields))
  return true
end

function DFFT.Profile.SetActiveForChar(name)
  ensureStores()
  if name and name ~= "" and not DB._profiles[name] then return false, "profile not found" end
  DB._charToProfile[charKey()] = (name ~= "" and name) or nil
  p("Active profile for this character:", DB._charToProfile[charKey()] or "<none>")
  return true
end
